package com.yztstudy.Listener;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.yztstudy.clients.ProductFeignClient;
import com.yztstudy.document.ProductDocument;
import com.yztstudy.entity.Product;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
 * 监听boot程序启动,完成ES数据导入
 */

@Component
@Service
public class SpringBootListener implements ApplicationRunner {

    @Autowired
    private RestHighLevelClient ESClient;

    @Resource
    private ProductFeignClient productFeignClient;

    // 索引的结构
    private String indexStr = "{\n" +
            "  \"mappings\": {\n" +
            "    \"properties\": {\n" +
            "      \"productId\":{\n" +
            "        \"type\": \"integer\"\n" +
            "      },\n" +
            "      \"productName\":{\n" +
            "        \"type\": \"text\",\n" +
            "        \"analyzer\": \"ik_smart\",\n" +
            "        \"copy_to\": \"all\"\n" +
            "      },\n" +
            "      \"categoryId\":{\n" +
            "        \"type\": \"integer\"\n" +
            "      },\n" +
            "      \"productTitle\":{\n" +
            "        \"type\": \"text\",\n" +
            "        \"analyzer\": \"ik_smart\",\n" +
            "        \"copy_to\": \"all\"\n" +
            "      },\n" +
            "      \"productIntro\":{\n" +
            "        \"type\":\"text\",\n" +
            "        \"analyzer\": \"ik_smart\",\n" +
            "        \"copy_to\": \"all\"\n" +
            "      },\n" +
            "      \"productPicture\":{\n" +
            "        \"type\": \"keyword\",\n" +
            "        \"index\": false\n" +
            "      },\n" +
            "      \"productPrice\":{\n" +
            "        \"type\": \"double\",\n" +
            "        \"index\": true\n" +
            "      },\n" +
            "      \"productSellingPrice\":{\n" +
            "        \"type\": \"double\"\n" +
            "      },\n" +
            "      \"productNum\":{\n" +
            "        \"type\": \"integer\"\n" +
            "      },\n" +
            "      \"productSales\":{\n" +
            "        \"type\": \"integer\"\n" +
            "      },\n" +
            "      \"all\":{\n" +
            "        \"type\": \"text\",\n" +
            "        \"analyzer\": \"ik_max_word\"\n" +
            "      }\n" +
            "    }\n" +
            "  }\n" +
            "}";

    /**
     * TODO 完成ES数据同步
     * @param args 运行参数
     * @throws Exception
     */
    @Override
    public void run(ApplicationArguments args) throws Exception {

        // TODO 1.判断ES中product这个索引是否存在
        GetIndexRequest request = new GetIndexRequest("product");
        boolean exists = ESClient.indices().exists(request, RequestOptions.DEFAULT);

        // TODO 2.不存在就是用Java代码创建
        if (!exists) // 不存在
        {
            CreateIndexRequest createIndexRequest = new CreateIndexRequest("product");
            createIndexRequest.source(indexStr, XContentType.JSON);
            ESClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);
        }

        // TODO 3.删除原来的数据
        else { // 存在
            DeleteByQueryRequest deleteByQueryRequest = new DeleteByQueryRequest("product");
            deleteByQueryRequest.setQuery(QueryBuilders.matchAllQuery()); // 全部删除
            ESClient.deleteByQuery(deleteByQueryRequest, RequestOptions.DEFAULT);
        }

        // TODO 4.查询全部的商品数据
        List<Product> products = productFeignClient.allList();

        // TODO 5.进行ES库的更新
        BulkRequest bulkRequest = new BulkRequest();
        ObjectMapper objectMapper = new ObjectMapper(); // JSON转换工具
        for (Product product : products)
        {
            ProductDocument productDocument = new ProductDocument(product);
            IndexRequest indexRequest = new IndexRequest("product"); // 插入数据的请求
            indexRequest.id(product.getProductId().toString()); // 设置文档的主键

            String objectJSON = objectMapper.writeValueAsString(productDocument); // 把对象转换成JSON
            indexRequest.source(objectJSON, XContentType.JSON);
            bulkRequest.add(indexRequest); // 放入批量操作中
        }

        // TODO 6.批量执行
        ESClient.bulk(bulkRequest, RequestOptions.DEFAULT);
    }
}
